/*
 * Copyright 2002-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.support;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Supplier;

import org.apache.commons.logging.Log;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyAccessorUtils;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.Aware;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.InjectionPoint;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.AutowiredPropertyMarker;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.MethodParameter;
import org.springframework.core.NamedThreadLocal;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodCallback;
import org.springframework.util.StringUtils;

/**
 * Abstract bean factory superclass that implements default bean creation,
 * with the full capabilities specified by the {@link RootBeanDefinition} class.
 * Implements the {@link org.springframework.beans.factory.config.AutowireCapableBeanFactory}
 * interface in addition to AbstractBeanFactory's {@link #createBean} method.
 *
 * <p>Provides bean creation (with constructor resolution), property population,
 * wiring (including autowiring), and initialization. Handles runtime bean
 * references, resolves managed collections, calls initialization methods, etc.
 * Supports autowiring constructors, properties by name, and properties by type.
 *
 * <p>The main template method to be implemented by subclasses is
 * {@link #resolveDependency(DependencyDescriptor, String, Set, TypeConverter)},
 * used for autowiring by type. In case of a factory which is capable of searching
 * its bean definitions, matching beans will typically be implemented through such
 * a search. For other factory styles, simplified matching algorithms can be implemented.
 *
 * <p>Note that this class does <i>not</i> assume or implement bean definition
 * registry capabilities. See {@link DefaultListableBeanFactory} for an implementation
 * of the {@link org.springframework.beans.factory.ListableBeanFactory} and
 * {@link BeanDefinitionRegistry} interfaces, which represent the API and SPI
 * view of such a factory, respectively.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @author Rob Harrop
 * @author Mark Fisher
 * @author Costin Leau
 * @author Chris Beams
 * @author Sam Brannen
 * @author Phillip Webb
 * @since 13.02.2004
 * @see RootBeanDefinition
 * @see DefaultListableBeanFactory
 * @see BeanDefinitionRegistry
 */

/**
 *  * [中] 核心Bean工厂抽象类，实现了完整的Bean创建能力：
 *  * 1. 支持构造器解析、属性填充、自动装配和初始化
 *  * 2. 处理运行时Bean引用、托管集合解析
 *  * 3. 支持构造器、按名称和按类型的自动装配
 */
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {

	/** Strategy for creating bean instances. */
	// [中] Bean实例化策略（默认使用CGLIB动态子类化策略）
	private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

	/** Resolver strategy for method parameter names. */
	// [中] 方法参数名解析器（用于构造器参数名解析）
	@Nullable
	private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();

	/** Whether to automatically try to resolve circular references between beans. */
	// [中] 是否允许循环引用（默认true）
	private boolean allowCircularReferences = true;

	/**
	 * Whether to resort to injecting a raw bean instance in case of circular reference,
	 * even if the injected bean eventually got wrapped.
	 */
	// [中] 是否允许注入原始Bean实例（即使最终会被包装，如AOP代理）
	private boolean allowRawInjectionDespiteWrapping = false;

	/**
	 * Dependency types to ignore on dependency check and autowire, as Set of
	 * Class objects: for example, String. Default is none.
	 */
	// [中] 需要忽略的依赖类型（如String等基础类型）
	private final Set<Class<?>> ignoredDependencyTypes = new HashSet<>();

	/**
	 * Dependency interfaces to ignore on dependency check and autowire, as Set of
	 * Class objects. By default, only the BeanFactory interface is ignored.
	 */
	// [中] 需要忽略的依赖接口（默认忽略BeanFactoryAware等接口）
	private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>();

	/**
	 * The name of the currently created bean, for implicit dependency registration
	 * on getBean etc invocations triggered from a user-specified Supplier callback.
	 */
	// [中] 当前正在创建的Bean名称（用于Supplier回调时的隐式依赖注册）
	private final NamedThreadLocal<String> currentlyCreatedBean = new NamedThreadLocal<>("Currently created bean");

	/** Cache of unfinished FactoryBean instances: FactoryBean name to BeanWrapper. */
	// [中] 未完成的FactoryBean实例缓存（工厂名称->Bean包装器）
	private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>();

	/** Cache of candidate factory methods per factory class. */
	// [中] 工厂类候选方法的缓存
	private final ConcurrentMap<Class<?>, Method[]> factoryMethodCandidateCache = new ConcurrentHashMap<>();

	/** Cache of filtered PropertyDescriptors: bean Class to PropertyDescriptor array. */
	// [中] 过滤后的属性描述符缓存（Bean类->属性描述符数组）
	private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
			new ConcurrentHashMap<>();


	/**
	 * Create a new AbstractAutowireCapableBeanFactory.
	 */
	// [中] 构造函数：默认忽略三个Aware接口的依赖
	public AbstractAutowireCapableBeanFactory() {
		super();
		ignoreDependencyInterface(BeanNameAware.class);
		ignoreDependencyInterface(BeanFactoryAware.class);
		ignoreDependencyInterface(BeanClassLoaderAware.class);
	}

	/**
	 * Create a new AbstractAutowireCapableBeanFactory with the given parent.
	 * @param parentBeanFactory parent bean factory, or {@code null} if none
	 */
	public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
		this();
		setParentBeanFactory(parentBeanFactory);
	}


	/**
	 * Set the instantiation strategy to use for creating bean instances.
	 * Default is CglibSubclassingInstantiationStrategy.
	 * @see CglibSubclassingInstantiationStrategy
	 */
	// [中] 设置实例化策略（可替换默认的CGLIB策略）
	public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
		this.instantiationStrategy = instantiationStrategy;
	}

	/**
	 * Return the instantiation strategy to use for creating bean instances.
	 * [中] 获取当前使用的Bean实例化策略
	 *
	 * @return 当前配置的实例化策略对象
	 */
	protected InstantiationStrategy getInstantiationStrategy() {
		return this.instantiationStrategy; // [中] 返回成员变量instantiationStrategy
	}

	/**
	 * Set the ParameterNameDiscoverer to use for resolving method parameter
	 * names if needed (e.g. for constructor names).
	 * [中] 设置参数名发现器，用于解析方法参数名（特别是构造器参数名）
	 *
	 * <p>Default is a {@link DefaultParameterNameDiscoverer}.
	 * [中] 默认使用DefaultParameterNameDiscoverer实现
	 *
	 * @param parameterNameDiscoverer 要设置的参数名发现器实例（可为null）
	 */
	public void setParameterNameDiscoverer(@Nullable ParameterNameDiscoverer parameterNameDiscoverer) {
		this.parameterNameDiscoverer = parameterNameDiscoverer; // [中] 设置成员变量
	}

	/**
	 * Return the ParameterNameDiscoverer to use for resolving method parameter
	 * names if needed.
	 * [中] 获取当前配置的参数名发现器
	 *
	 * @return 当前配置的参数名发现器（可能为null）
	 */
	@Nullable
	protected ParameterNameDiscoverer getParameterNameDiscoverer() {
		return this.parameterNameDiscoverer; // [中] 返回成员变量parameterNameDiscoverer
	}

	/**
	 * Set whether to allow circular references between beans - and automatically
	 * try to resolve them.
	 * <p>Note that circular reference resolution means that one of the involved beans
	 * will receive a reference to another bean that is not fully initialized yet.
	 * [中] 设置是否允许循环引用：
	 * 1. 开启后Spring会尝试通过提前暴露引用来解决循环依赖
	 * 2. 注意这会使得Bean可能接收到未完全初始化的依赖
	 * 3. 建议重构代码避免循环依赖
	 */
	public void setAllowCircularReferences(boolean allowCircularReferences) {
		this.allowCircularReferences = allowCircularReferences;
	}

	/**
	 * Set whether to allow the raw injection of a bean instance into some other
	 * bean's property, despite the injected bean eventually getting wrapped
	 * (for example, through AOP auto-proxying).
	 * <p>This will only be used as a last resort in case of a circular reference
	 * that cannot be resolved otherwise: essentially, preferring a raw instance
	 * getting injected over a failure of the entire bean wiring process.
	 * <p>Default is "false", as of Spring 2.0. Turn this on to allow for non-wrapped
	 * raw beans injected into some of your references, which was Spring 1.2's
	 * (arguably unclean) default behavior.
	 * <p><b>NOTE:</b> It is generally recommended to not rely on circular references
	 * between your beans, in particular with auto-proxying involved.
	 * @see #setAllowCircularReferences
	 */
	public void setAllowRawInjectionDespiteWrapping(boolean allowRawInjectionDespiteWrapping) {
		this.allowRawInjectionDespiteWrapping = allowRawInjectionDespiteWrapping;
	}

	/**
	 * Ignore the given dependency type for autowiring:
	 * for example, String. Default is none.
	 */
	public void ignoreDependencyType(Class<?> type) {
		this.ignoredDependencyTypes.add(type);
	}

	/**
	 * Ignore the given dependency interface for autowiring.
	 * <p>This will typically be used by application contexts to register
	 * dependencies that are resolved in other ways, like BeanFactory through
	 * BeanFactoryAware or ApplicationContext through ApplicationContextAware.
	 * <p>By default, only the BeanFactoryAware interface is ignored.
	 * For further types to ignore, invoke this method for each type.
	 * @see org.springframework.beans.factory.BeanFactoryAware
	 * @see org.springframework.context.ApplicationContextAware
	 */
	public void ignoreDependencyInterface(Class<?> ifc) {
		this.ignoredDependencyInterfaces.add(ifc);
	}

	@Override
	public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
		super.copyConfigurationFrom(otherFactory);
		if (otherFactory instanceof AbstractAutowireCapableBeanFactory) {
			AbstractAutowireCapableBeanFactory otherAutowireFactory =
					(AbstractAutowireCapableBeanFactory) otherFactory;
			this.instantiationStrategy = otherAutowireFactory.instantiationStrategy;
			this.allowCircularReferences = otherAutowireFactory.allowCircularReferences;
			this.ignoredDependencyTypes.addAll(otherAutowireFactory.ignoredDependencyTypes);
			this.ignoredDependencyInterfaces.addAll(otherAutowireFactory.ignoredDependencyInterfaces);
		}
	}


	//-------------------------------------------------------------------------
	// Bean实例创建相关方法
	//-------------------------------------------------------------------------

	@Override
	@SuppressWarnings("unchecked")
	public <T> T createBean(Class<T> beanClass) throws BeansException {
		// [中] 为指定类创建原型作用域的Bean实例
		RootBeanDefinition bd = new RootBeanDefinition(beanClass);
		bd.setScope(SCOPE_PROTOTYPE);
		bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());
		return (T) createBean(beanClass.getName(), bd, null);
	}

	@Override
	public void autowireBean(Object existingBean) {
		// [中] 对现有Bean实例进行自动装配
		RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean));
		bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
		bd.allowCaching = ClassUtils.isCacheSafe(bd.getBeanClass(), getBeanClassLoader());
		BeanWrapper bw = new BeanWrapperImpl(existingBean);
		initBeanWrapper(bw);  // [中] 初始化BeanWrapper
		populateBean(bd.getBeanClass().getName(), bd, bw);  // [中] 填充属性
	}

	@Override
	public Object configureBean(Object existingBean, String beanName) throws BeansException {
		// [中] 配置现有Bean实例（合并定义+属性填充+初始化）
		markBeanAsCreated(beanName);
		BeanDefinition mbd = getMergedBeanDefinition(beanName);
		// [中] 处理原型作用域的Bean定义
		RootBeanDefinition bd = null;
		if (mbd instanceof RootBeanDefinition) {
			RootBeanDefinition rbd = (RootBeanDefinition) mbd;
			bd = (rbd.isPrototype() ? rbd : rbd.cloneBeanDefinition());
		}
		if (bd == null) {
			bd = new RootBeanDefinition(mbd);
		}
		if (!bd.isPrototype()) {
			bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
			bd.allowCaching = ClassUtils.isCacheSafe(ClassUtils.getUserClass(existingBean), getBeanClassLoader());
		}
		BeanWrapper bw = new BeanWrapperImpl(existingBean);
		initBeanWrapper(bw);
		populateBean(beanName, bd, bw);
		return initializeBean(beanName, existingBean, bd);  // [中] 执行初始化回调
	}


	//-------------------------------------------------------------------------
	// Specialized methods for fine-grained control over the bean lifecycle
	//-------------------------------------------------------------------------

	@Override
	public Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
		// Use non-singleton bean definition, to avoid registering bean as dependent bean.
		RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
		bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
		return createBean(beanClass.getName(), bd, null);
	}

	@Override
	public Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
		// Use non-singleton bean definition, to avoid registering bean as dependent bean.
		final RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
		bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
		if (bd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR) {
			return autowireConstructor(beanClass.getName(), bd, null, null).getWrappedInstance();
		}
		else {
			Object bean;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				bean = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						getInstantiationStrategy().instantiate(bd, null, parent),
						getAccessControlContext());
			}
			else {
				bean = getInstantiationStrategy().instantiate(bd, null, parent);
			}
			populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean));
			return bean;
		}
	}

	@Override
	public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
			throws BeansException {

		if (autowireMode == AUTOWIRE_CONSTRUCTOR) {
			throw new IllegalArgumentException("AUTOWIRE_CONSTRUCTOR not supported for existing bean instance");
		}
		// Use non-singleton bean definition, to avoid registering bean as dependent bean.
		RootBeanDefinition bd =
				new RootBeanDefinition(ClassUtils.getUserClass(existingBean), autowireMode, dependencyCheck);
		bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
		BeanWrapper bw = new BeanWrapperImpl(existingBean);
		initBeanWrapper(bw);
		populateBean(bd.getBeanClass().getName(), bd, bw);
	}

	@Override
	public void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException {
		markBeanAsCreated(beanName);
		BeanDefinition bd = getMergedBeanDefinition(beanName);
		BeanWrapper bw = new BeanWrapperImpl(existingBean);
		initBeanWrapper(bw);
		applyPropertyValues(beanName, bd, bw, bd.getPropertyValues());
	}

	@Override
	public Object initializeBean(Object existingBean, String beanName) {
		return initializeBean(beanName, existingBean, null);
	}

	@Override
	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

	/**
	 * 对指定 Bean 应用所有注册的 BeanPostProcessor 的初始化后处理逻辑。
	 * 该方法会按顺序调用每个 BeanPostProcessor 的 postProcessAfterInitialization 方法，
	 * 允许处理器对 Bean 实例进行最终修改或增强，如代理创建、注解处理等。
	 *
	 * <p>BeanPostProcessor 是 Spring 容器中的核心扩展点之一，用于在 Bean 初始化前后插入自定义逻辑。
	 * 此方法实现了后置处理器链的调用机制，确保每个处理器按注册顺序依次作用于目标 Bean。
	 *
	 * <p>执行流程：
	 * <ol>
	 *   <li>从 BeanFactory 获取所有注册的 BeanPostProcessor 实例</li>
	 *   <li>按顺序遍历处理器列表，依次调用其 postProcessAfterInitialization 方法</li>
	 *   <li>将前一个处理器的返回值作为下一个处理器的输入</li>
	 *   <li>若某个处理器返回 null，则终止处理链并返回当前结果</li>
	 *   <li>返回最后一个处理器的返回值作为最终结果</li>
	 * </ol>
	 *
	 * <p>典型应用场景：
	 * <ul>
	 *   <li>AOP 代理创建（如 @Transactional、@Async 注解处理）</li>
	 *   <li>注解驱动的依赖注入（如 @PostConstruct、@Resource）</li>
	 *   <li>Bean 实例的验证或配置检查</li>
	 *   <li>运行时 Bean 属性修改或增强</li>
	 * </ul>
	 *
	 * <p>注意事项：
	 * <ul>
	 *   <li>处理器返回 null 会提前终止处理链，需谨慎实现</li>
	 *   <li>处理器的执行顺序由注册顺序决定，可通过 Ordered 接口调整</li>
	 *   <li>若 Bean 被代理，此处返回的可能是代理对象而非原始实例</li>
	 * </ul>
	 *
	 * @param existingBean 初始化完成的 Bean 实例
	 * @param beanName     Bean 的名称
	 * @return 经过所有处理器处理后的最终 Bean 实例
	 * @throws BeansException 如果任何处理器抛出异常
	 *
	 * @see BeanPostProcessor#postProcessAfterInitialization
	 * @see #applyBeanPostProcessorsBeforeInitialization
	 * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#getBeanPostProcessors()
	 */
	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		// 遍历所有注册的 BeanPostProcessor
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			// 应用当前处理器的初始化后处理逻辑
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				// 若处理器返回 null，则终止处理链并返回最后一个有效值
				return result;
			}
			// 更新结果为当前处理器的返回值，作为下一个处理器的输入
			result = current;
		}
		// 返回最终处理后的 Bean 实例
		return result;
	}

	@Override
	public void destroyBean(Object existingBean) {
		new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();
	}


	//-------------------------------------------------------------------------
	// Delegate methods for resolving injection points
	//-------------------------------------------------------------------------

	@Override
	public Object resolveBeanByName(String name, DependencyDescriptor descriptor) {
		InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
		try {
			return getBean(name, descriptor.getDependencyType());
		}
		finally {
			ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
		}
	}

	@Override
	@Nullable
	public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException {
		return resolveDependency(descriptor, requestingBeanName, null, null);
	}


	//---------------------------------------------------------------------
	// Implementation of relevant AbstractBeanFactory template methods
	//---------------------------------------------------------------------
	/**
	 * Spring Bean 工厂创建 Bean 实例的核心方法。
	 *
	 * 该方法负责：
	 * 1. 解析 Bean 类（如果尚未解析）
	 * 2. 准备方法覆盖（处理 lookup-method 和 replace-method）
	 * 3. 允许 Bean 后置处理器提前介入（如创建代理）
	 * 4. 调用实际的 Bean 创建逻辑
	 * 5. 处理创建过程中可能出现的各种异常
	 *
	 * @param beanName Bean 的名称
	 * @param mbd 合并后的 Bean 定义
	 * @param args 创建 Bean 时使用的构造函数参数（如果有）
	 * @return 创建的 Bean 实例
	 * @throws BeanCreationException 如果 Bean 创建失败
	 * @see #doCreateBean
	 */
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// 记录 Bean 创建开始的跟踪日志
		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// 确保 Bean 类已被解析，并处理动态解析的类
		// 动态解析的类不能存储在共享的合并 Bean 定义中，因此需要克隆 Bean 定义
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// 准备方法覆盖（处理 lookup-method 和 replace-method 配置）,
		// 主要的功能就是让单例中引用的多例没每次都不同，如果没有这两个标签，那么就算是多例的，
		// 他在单例里面注入进入也是没法获取到新对象的，说简单点就是多例失效了
		// 这些配置允许在运行时动态替换 Bean 中的方法实现
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// 允许 Bean 后置处理器在实例化之前介入
			// 这是 Spring AOP 实现的关键扩展点之一，允许返回代理对象而非目标 Bean，，
			// 如果有实现来InstantiationAwareBeanPostProcessor接口，也会在这里创建对象
			//如果在此处创建了，就不走doCreateBean
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				// 如果后置处理器返回了非空对象，则跳过常规的 Bean 创建流程，直接返回该对象
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			// 实际执行 Bean 创建的核心方法
			// 包含实例化、属性填充、初始化等步骤
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// 已包含完整上下文的 Bean 创建异常，直接重新抛出
			throw ex;
		}
		catch (Throwable ex) {
			// 处理其他未预期的异常，封装为 Bean 创建异常
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}
	/**
	 * 实际创建指定的 Bean。此时已完成创建前的处理，例如检查 postProcessBeforeInstantiation 回调。
	 * <p>区分默认 Bean 实例化、工厂方法使用和构造函数自动装配。
	 *
	 * @param beanName Bean 的名称
	 * @param mbd Bean 的合并定义
	 * @param args 用于构造函数或工厂方法调用的显式参数
	 * @return Bean 的新实例
	 * @throws BeanCreationException 如果 Bean 创建失败
	 */
	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		// 1. 实例化 Bean
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			// 从工厂 Bean 实例缓存中获取（处理 FactoryBean 场景）
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			// 创建 Bean 实例（调用 createBeanInstance 选择实例化策略）
			//进行实例化，且返回bean属性的包装类，
			// 我们前面自定义的一些属性转换也都是在这里进行处理（比如：实现PropertyEditorSupport的属性编辑器和属性转换器）
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// 2. 应用 MergedBeanDefinitionPostProcessor
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					// 允许后置处理器修改合并后的 Bean 定义
					//一些注解就是在这里处理的了
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				} catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"合并 Bean 定义的后处理失败", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// 3. 处理循环引用（提前暴露单例工厂）
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("提前缓存 Bean '" + beanName +
						"' 以允许解析潜在的循环引用");
			}
			// 添加早期单例工厂，用于生成 Bean 的早期引用
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// 4. 初始化 Bean 实例
		Object exposedObject = bean;
		try {
			// 4.1 填充 Bean 属性（依赖注入）
			populateBean(beanName, mbd, instanceWrapper);
			// 4.2 初始化 Bean（调用生命周期方法）
				exposedObject = initializeBean(beanName, exposedObject, mbd);
		} catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			} else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Bean 初始化失败", ex);
			}
		}

		// 5. 处理循环引用（解析早期单例）
		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					// 如果 Bean 未被包装，直接使用早期引用（解决循环依赖）
					exposedObject = earlySingletonReference;
				} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					// 检查是否有依赖 Bean 使用了原始 Bean 引用
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"名为 '" + beanName + "' 的 Bean 作为循环引用的一部分被注入到其他 Bean [" +
										StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
										"] 中，但最终被包装。这意味着其他 Bean 没有使用 Bean 的最终版本。");
					}
				}
			}
		}

		// 6. 注册可销毁 Bean（处理生命周期）
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		} catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "无效的销毁签名", ex);
		}

		return exposedObject;
	}

	@Override
	@Nullable
	protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
		Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);
		// Apply SmartInstantiationAwareBeanPostProcessors to predict the
		// eventual type after a before-instantiation shortcut.
		if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			boolean matchingOnlyFactoryBean = typesToMatch.length == 1 && typesToMatch[0] == FactoryBean.class;
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					Class<?> predicted = ibp.predictBeanType(targetType, beanName);
					if (predicted != null &&
							(!matchingOnlyFactoryBean || FactoryBean.class.isAssignableFrom(predicted))) {
						return predicted;
					}
				}
			}
		}
		return targetType;
	}

	/**
	 * Determine the target type for the given bean definition.
	 * @param beanName the name of the bean (for error handling purposes)
	 * @param mbd the merged bean definition for the bean
	 * @param typesToMatch the types to match in case of internal type matching purposes
	 * (also signals that the returned {@code Class} will never be exposed to application code)
	 * @return the type for the bean if determinable, or {@code null} otherwise
	 */
	@Nullable
	protected Class<?> determineTargetType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
		Class<?> targetType = mbd.getTargetType();
		if (targetType == null) {
			targetType = (mbd.getFactoryMethodName() != null ?
					getTypeForFactoryMethod(beanName, mbd, typesToMatch) :
					resolveBeanClass(mbd, beanName, typesToMatch));
			if (ObjectUtils.isEmpty(typesToMatch) || getTempClassLoader() == null) {
				mbd.resolvedTargetType = targetType;
			}
		}
		return targetType;
	}

	/**
	 * Determine the target type for the given bean definition which is based on
	 * a factory method. Only called if there is no singleton instance registered
	 * for the target bean already.
	 * <p>This implementation determines the type matching {@link #createBean}'s
	 * different creation strategies. As far as possible, we'll perform static
	 * type checking to avoid creation of the target bean.
	 * @param beanName the name of the bean (for error handling purposes)
	 * @param mbd the merged bean definition for the bean
	 * @param typesToMatch the types to match in case of internal type matching purposes
	 * (also signals that the returned {@code Class} will never be exposed to application code)
	 * @return the type for the bean if determinable, or {@code null} otherwise
	 * @see #createBean
	 */
	@Nullable
	protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
		ResolvableType cachedReturnType = mbd.factoryMethodReturnType;
		if (cachedReturnType != null) {
			return cachedReturnType.resolve();
		}

		Class<?> commonType = null;
		Method uniqueCandidate = mbd.factoryMethodToIntrospect;

		if (uniqueCandidate == null) {
			Class<?> factoryClass;
			boolean isStatic = true;

			String factoryBeanName = mbd.getFactoryBeanName();
			if (factoryBeanName != null) {
				if (factoryBeanName.equals(beanName)) {
					throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
							"factory-bean reference points back to the same bean definition");
				}
				// Check declared factory method return type on factory class.
				factoryClass = getType(factoryBeanName);
				isStatic = false;
			}
			else {
				// Check declared factory method return type on bean class.
				factoryClass = resolveBeanClass(mbd, beanName, typesToMatch);
			}

			if (factoryClass == null) {
				return null;
			}
			factoryClass = ClassUtils.getUserClass(factoryClass);

			// If all factory methods have the same return type, return that type.
			// Can't clearly figure out exact method due to type converting / autowiring!
			int minNrOfArgs =
					(mbd.hasConstructorArgumentValues() ? mbd.getConstructorArgumentValues().getArgumentCount() : 0);
			Method[] candidates = this.factoryMethodCandidateCache.computeIfAbsent(factoryClass,
					clazz -> ReflectionUtils.getUniqueDeclaredMethods(clazz, ReflectionUtils.USER_DECLARED_METHODS));

			for (Method candidate : candidates) {
				if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate) &&
						candidate.getParameterCount() >= minNrOfArgs) {
					// Declared type variables to inspect?
					if (candidate.getTypeParameters().length > 0) {
						try {
							// Fully resolve parameter names and argument values.
							Class<?>[] paramTypes = candidate.getParameterTypes();
							String[] paramNames = null;
							ParameterNameDiscoverer pnd = getParameterNameDiscoverer();
							if (pnd != null) {
								paramNames = pnd.getParameterNames(candidate);
							}
							ConstructorArgumentValues cav = mbd.getConstructorArgumentValues();
							Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
							Object[] args = new Object[paramTypes.length];
							for (int i = 0; i < args.length; i++) {
								ConstructorArgumentValues.ValueHolder valueHolder = cav.getArgumentValue(
										i, paramTypes[i], (paramNames != null ? paramNames[i] : null), usedValueHolders);
								if (valueHolder == null) {
									valueHolder = cav.getGenericArgumentValue(null, null, usedValueHolders);
								}
								if (valueHolder != null) {
									args[i] = valueHolder.getValue();
									usedValueHolders.add(valueHolder);
								}
							}
							Class<?> returnType = AutowireUtils.resolveReturnTypeForFactoryMethod(
									candidate, args, getBeanClassLoader());
							uniqueCandidate = (commonType == null && returnType == candidate.getReturnType() ?
									candidate : null);
							commonType = ClassUtils.determineCommonAncestor(returnType, commonType);
							if (commonType == null) {
								// Ambiguous return types found: return null to indicate "not determinable".
								return null;
							}
						}
						catch (Throwable ex) {
							if (logger.isDebugEnabled()) {
								logger.debug("Failed to resolve generic return type for factory method: " + ex);
							}
						}
					}
					else {
						uniqueCandidate = (commonType == null ? candidate : null);
						commonType = ClassUtils.determineCommonAncestor(candidate.getReturnType(), commonType);
						if (commonType == null) {
							// Ambiguous return types found: return null to indicate "not determinable".
							return null;
						}
					}
				}
			}

			mbd.factoryMethodToIntrospect = uniqueCandidate;
			if (commonType == null) {
				return null;
			}
		}

		// Common return type found: all factory methods return same type. For a non-parameterized
		// unique candidate, cache the full type declaration context of the target factory method.
		cachedReturnType = (uniqueCandidate != null ?
				ResolvableType.forMethodReturnType(uniqueCandidate) : ResolvableType.forClass(commonType));
		mbd.factoryMethodReturnType = cachedReturnType;
		return cachedReturnType.resolve();
	}

	/**
	 * This implementation attempts to query the FactoryBean's generic parameter metadata
	 * if present to determine the object type. If not present, i.e. the FactoryBean is
	 * declared as a raw type, checks the FactoryBean's {@code getObjectType} method
	 * on a plain instance of the FactoryBean, without bean properties applied yet.
	 * If this doesn't return a type yet, and {@code allowInit} is {@code true} a
	 * full creation of the FactoryBean is used as fallback (through delegation to the
	 * superclass's implementation).
	 * <p>The shortcut check for a FactoryBean is only applied in case of a singleton
	 * FactoryBean. If the FactoryBean instance itself is not kept as singleton,
	 * it will be fully created to check the type of its exposed object.
	 */
	@Override
	protected ResolvableType getTypeForFactoryBean(String beanName, RootBeanDefinition mbd, boolean allowInit) {
		// Check if the bean definition itself has defined the type with an attribute
		ResolvableType result = getTypeForFactoryBeanFromAttributes(mbd);
		if (result != ResolvableType.NONE) {
			return result;
		}

		ResolvableType beanType =
				(mbd.hasBeanClass() ? ResolvableType.forClass(mbd.getBeanClass()) : ResolvableType.NONE);

		// For instance supplied beans try the target type and bean class
		if (mbd.getInstanceSupplier() != null) {
			result = getFactoryBeanGeneric(mbd.targetType);
			if (result.resolve() != null) {
				return result;
			}
			result = getFactoryBeanGeneric(beanType);
			if (result.resolve() != null) {
				return result;
			}
		}

		// Consider factory methods
		String factoryBeanName = mbd.getFactoryBeanName();
		String factoryMethodName = mbd.getFactoryMethodName();

		// Scan the factory bean methods
		if (factoryBeanName != null) {
			if (factoryMethodName != null) {
				// Try to obtain the FactoryBean's object type from its factory method
				// declaration without instantiating the containing bean at all.
				BeanDefinition factoryBeanDefinition = getBeanDefinition(factoryBeanName);
				Class<?> factoryBeanClass;
				if (factoryBeanDefinition instanceof AbstractBeanDefinition &&
						((AbstractBeanDefinition) factoryBeanDefinition).hasBeanClass()) {
					factoryBeanClass = ((AbstractBeanDefinition) factoryBeanDefinition).getBeanClass();
				}
				else {
					RootBeanDefinition fbmbd = getMergedBeanDefinition(factoryBeanName, factoryBeanDefinition);
					factoryBeanClass = determineTargetType(factoryBeanName, fbmbd);
				}
				if (factoryBeanClass != null) {
					result = getTypeForFactoryBeanFromMethod(factoryBeanClass, factoryMethodName);
					if (result.resolve() != null) {
						return result;
					}
				}
			}
			// If not resolvable above and the referenced factory bean doesn't exist yet,
			// exit here - we don't want to force the creation of another bean just to
			// obtain a FactoryBean's object type...
			if (!isBeanEligibleForMetadataCaching(factoryBeanName)) {
				return ResolvableType.NONE;
			}
		}

		// If we're allowed, we can create the factory bean and call getObjectType() early
		if (allowInit) {
			FactoryBean<?> factoryBean = (mbd.isSingleton() ?
					getSingletonFactoryBeanForTypeCheck(beanName, mbd) :
					getNonSingletonFactoryBeanForTypeCheck(beanName, mbd));
			if (factoryBean != null) {
				// Try to obtain the FactoryBean's object type from this early stage of the instance.
				Class<?> type = getTypeForFactoryBean(factoryBean);
				if (type != null) {
					return ResolvableType.forClass(type);
				}
				// No type found for shortcut FactoryBean instance:
				// fall back to full creation of the FactoryBean instance.
				return super.getTypeForFactoryBean(beanName, mbd, true);
			}
		}

		if (factoryBeanName == null && mbd.hasBeanClass() && factoryMethodName != null) {
			// No early bean instantiation possible: determine FactoryBean's type from
			// static factory method signature or from class inheritance hierarchy...
			return getTypeForFactoryBeanFromMethod(mbd.getBeanClass(), factoryMethodName);
		}
		result = getFactoryBeanGeneric(beanType);
		if (result.resolve() != null) {
			return result;
		}
		return ResolvableType.NONE;
	}

	private ResolvableType getFactoryBeanGeneric(@Nullable ResolvableType type) {
		if (type == null) {
			return ResolvableType.NONE;
		}
		return type.as(FactoryBean.class).getGeneric();
	}

	/**
	 * Introspect the factory method signatures on the given bean class,
	 * trying to find a common {@code FactoryBean} object type declared there.
	 * @param beanClass the bean class to find the factory method on
	 * @param factoryMethodName the name of the factory method
	 * @return the common {@code FactoryBean} object type, or {@code null} if none
	 */
	private ResolvableType getTypeForFactoryBeanFromMethod(Class<?> beanClass, String factoryMethodName) {
		// CGLIB subclass methods hide generic parameters; look at the original user class.
		Class<?> factoryBeanClass = ClassUtils.getUserClass(beanClass);
		FactoryBeanMethodTypeFinder finder = new FactoryBeanMethodTypeFinder(factoryMethodName);
		ReflectionUtils.doWithMethods(factoryBeanClass, finder, ReflectionUtils.USER_DECLARED_METHODS);
		return finder.getResult();
	}

	/**
	 * This implementation attempts to query the FactoryBean's generic parameter metadata
	 * if present to determine the object type. If not present, i.e. the FactoryBean is
	 * declared as a raw type, checks the FactoryBean's {@code getObjectType} method
	 * on a plain instance of the FactoryBean, without bean properties applied yet.
	 * If this doesn't return a type yet, a full creation of the FactoryBean is
	 * used as fallback (through delegation to the superclass's implementation).
	 * <p>The shortcut check for a FactoryBean is only applied in case of a singleton
	 * FactoryBean. If the FactoryBean instance itself is not kept as singleton,
	 * it will be fully created to check the type of its exposed object.
	 */
	@Override
	@Deprecated
	@Nullable
	protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
		return getTypeForFactoryBean(beanName, mbd, true).resolve();
	}

	/**
	 * Obtain a reference for early access to the specified bean,
	 * typically for the purpose of resolving a circular reference.
	 * @param beanName the name of the bean (for error handling purposes)
	 * @param mbd the merged bean definition for the bean
	 * @param bean the raw bean instance
	 * @return the object to expose as bean reference
	 */
	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;
	}


	//---------------------------------------------------------------------
	// Implementation methods
	//---------------------------------------------------------------------

	/**
	 * Obtain a "shortcut" singleton FactoryBean instance to use for a
	 * {@code getObjectType()} call, without full initialization of the FactoryBean.
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @return the FactoryBean instance, or {@code null} to indicate
	 * that we couldn't obtain a shortcut FactoryBean instance
	 */
	@Nullable
	private FactoryBean<?> getSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) {
		synchronized (getSingletonMutex()) {
			BeanWrapper bw = this.factoryBeanInstanceCache.get(beanName);
			if (bw != null) {
				return (FactoryBean<?>) bw.getWrappedInstance();
			}
			Object beanInstance = getSingleton(beanName, false);
			if (beanInstance instanceof FactoryBean) {
				return (FactoryBean<?>) beanInstance;
			}
			if (isSingletonCurrentlyInCreation(beanName) ||
					(mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) {
				return null;
			}

			Object instance;
			try {
				// Mark this bean as currently in creation, even if just partially.
				beforeSingletonCreation(beanName);
				// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
				instance = resolveBeforeInstantiation(beanName, mbd);
				if (instance == null) {
					bw = createBeanInstance(beanName, mbd, null);
					instance = bw.getWrappedInstance();
				}
			}
			catch (UnsatisfiedDependencyException ex) {
				// Don't swallow, probably misconfiguration...
				throw ex;
			}
			catch (BeanCreationException ex) {
				// Instantiation failure, maybe too early...
				if (logger.isDebugEnabled()) {
					logger.debug("Bean creation exception on singleton FactoryBean type check: " + ex);
				}
				onSuppressedException(ex);
				return null;
			}
			finally {
				// Finished partial creation of this bean.
				afterSingletonCreation(beanName);
			}

			FactoryBean<?> fb = getFactoryBean(beanName, instance);
			if (bw != null) {
				this.factoryBeanInstanceCache.put(beanName, bw);
			}
			return fb;
		}
	}

	/**
	 * Obtain a "shortcut" non-singleton FactoryBean instance to use for a
	 * {@code getObjectType()} call, without full initialization of the FactoryBean.
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @return the FactoryBean instance, or {@code null} to indicate
	 * that we couldn't obtain a shortcut FactoryBean instance
	 */
	@Nullable
	private FactoryBean<?> getNonSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) {
		if (isPrototypeCurrentlyInCreation(beanName)) {
			return null;
		}

		Object instance;
		try {
			// Mark this bean as currently in creation, even if just partially.
			beforePrototypeCreation(beanName);
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			instance = resolveBeforeInstantiation(beanName, mbd);
			if (instance == null) {
				BeanWrapper bw = createBeanInstance(beanName, mbd, null);
				instance = bw.getWrappedInstance();
			}
		}
		catch (UnsatisfiedDependencyException ex) {
			// Don't swallow, probably misconfiguration...
			throw ex;
		}
		catch (BeanCreationException ex) {
			// Instantiation failure, maybe too early...
			if (logger.isDebugEnabled()) {
				logger.debug("Bean creation exception on non-singleton FactoryBean type check: " + ex);
			}
			onSuppressedException(ex);
			return null;
		}
		finally {
			// Finished partial creation of this bean.
			afterPrototypeCreation(beanName);
		}

		return getFactoryBean(beanName, instance);
	}

	/**
	 * 将合并的Bean定义后处理器应用到指定的Bean定义上，
	 * 调用它们的{@code postProcessMergedBeanDefinition}方法。
	 * <p>此方法会遍历容器中所有的Bean后处理器，识别出实现了
	 * MergedBeanDefinitionPostProcessor接口的后处理器，并触发其
	 * 对合并后的Bean定义进行处理。这是Spring Bean生命周期中
	 * 允许修改Bean定义元数据的关键扩展点。
	 *
	 * @param mbd 要处理的合并后的Bean定义（包含父类定义合并后的完整信息）
	 * @param beanType 被管理的Bean实例的实际类型（可能是子类或代理类型）
	 * @param beanName Bean的名称
	 *
	 * @see MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
	 *      后处理器接口方法，用于修改合并后的Bean定义
	 * @see BeanPostProcessor Spring通用后处理器接口
	 * @see RootBeanDefinition 合并后的Bean定义类
	 */
	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		// 遍历容器中所有注册的Bean后处理器
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			// 筛选出实现了MergedBeanDefinitionPostProcessor接口的后处理器
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				// 触发后处理器对Bean定义的处理逻辑
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}

		}
	}
	/**
	 * 在实例化前应用后置处理器，判断是否存在针对指定Bean的实例化前快捷方式。
	 * <p>该方法是Spring Bean生命周期中的优化步骤，允许后置处理器在Bean正式实例化前
	 * 直接返回一个实例（如代理对象），从而跳过完整的实例化流程。
	 *
	 * @param beanName Bean的名称
	 * @param mbd Bean的合并定义（RootBeanDefinition）
	 * @return 后置处理器确定的Bean实例，若无则返回null
	 *
	 * @see BeanPostProcessor#postProcessBeforeInstantiation 实例化前处理方法
	 * @see BeanPostProcessor#postProcessAfterInitialization 初始化后处理方法
	 * @see InstantiationAwareBeanPostProcessor Spring实例化相关后置处理器接口
	 */
	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;

		// 1. 检查是否已完成实例化前解析（避免重复处理）
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// 2. 确保Bean类已解析且非合成类
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				// 3. 确定Bean的目标类型（处理泛型、工厂方法等场景）
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					// 4. 应用实例化前后置处理器（核心优化点）
					//   允许后置处理器直接返回Bean实例，跳过常规实例化流程
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						// 5. 若后置处理器返回了Bean实例，应用初始化后处理器
						//   例如：对提前创建的代理对象进行后续初始化
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			// 6. 标记是否已完成实例化前解析
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

	/**
	 * 将实例化感知Bean后置处理器应用于指定的Bean定义（通过类和名称），
	 * 调用它们的{@code postProcessBeforeInstantiation}方法。
	 * <p>后置处理器返回的对象将直接作为Bean使用，而不是实例化目标Bean。
	 * 若后置处理器返回{@code null}，则会继续实例化目标Bean。
	 *
	 * @param beanClass 要实例化的Bean的类
	 * @param beanName Bean的名称
	 * @return 用于替代目标Bean的实例，若无则返回null
	 *
	 * @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
	 *      实例化前处理方法，允许后置处理器提前创建Bean实例
	 * @see BeanPostProcessor Spring通用后置处理器接口
	 * @see AbstractBeanFactory#resolveBeforeInstantiation 调用此方法的上层逻辑
	 */
	@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		// 遍历容器中所有注册的Bean后置处理器
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			// 筛选出实现了InstantiationAwareBeanPostProcessor接口的后置处理器
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				// 调用postProcessBeforeInstantiation方法，实例化之前调用， 允许提前创建Bean实例
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				// 若后置处理器返回非null实例，则直接使用该实例，跳过常规实例化流程
				if (result != null) {
					return result;
				}
			}
		}
		// 所有后置处理器均未返回实例，继续常规实例化
		return null;
	}

	/**
	 * 创建指定 Bean 的新实例，使用适当的实例化策略：
	 * 工厂方法、构造函数自动装配或简单实例化。
	 *
	 * 该方法是 Bean 实例化的入口，会依次尝试以下策略：
	 * 1. 实例供应商（instanceSupplier）
	 * 2. 工厂方法（factory-method）
	 * 3. 构造函数自动装配（constructor autowiring）
	 * 4. 无参构造函数实例化（default instantiation）
	 *
	 * @param beanName Bean 的名称
	 * @param mbd Bean 的合并定义
	 * @param args 用于构造函数或工厂方法调用的显式参数
	 * @return 封装了新实例的 BeanWrapper
	 * @throws BeanCreationException 如果实例化失败
	 */
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// 1. 解析 Bean 类（如果尚未解析）
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		// 2. 检查类可见性：非公共类需要特殊允许
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean 类不是公共类，且不允许非公共访问: " + beanClass.getName());
		}

		// 3. 尝试使用实例供应商（instanceSupplier）创建实例,有设置Suppler属性，就在这进行实例化，拓展点是在BeanFactoryPostProcessor实现的
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		// 4. 尝试使用工厂方法（factory-method）创建实例
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// 5. 检查是否已解析构造函数（优化路径）
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				// 如果已解析过构造函数或工厂方法，直接使用缓存结果
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			// 根据是否需要自动装配选择不同的实例化方式
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			} else {
				return instantiateBean(beanName, mbd);
			}
		}

		// 6. 尝试构造函数自动装配
		// 条件：存在构造函数后处理器、自动装配模式为构造函数、有构造参数值或传入了参数
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// 7. 尝试使用首选构造函数（preferred constructors）
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// 8. 最后尝试无参构造函数实例化
		return instantiateBean(beanName, mbd);
	}
	/**
	 * 从给定的Supplier获取一个bean实例，并将其包装在BeanWrapper中。
	 * 此方法用于支持通过Supplier函数式接口创建bean实例，是Spring 5.0引入的特性。
	 *
	 * @param instanceSupplier 配置的Supplier函数，用于生成bean实例
	 * @param beanName 对应的bean名称，用于标识当前创建的bean
	 * @return 新实例的BeanWrapper，提供对bean属性的访问和设置能力
	 * @since 5.0
	 * @see #getObjectForBeanInstance 用于处理bean实例的后续步骤（如代理创建）
	 */
	protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
		Object instance;

		// 记录当前正在创建的外层bean名称（如果有）
		// 用于处理嵌套创建的场景（如A依赖B，创建A时触发B的创建）
		String outerBean = this.currentlyCreatedBean.get();
		this.currentlyCreatedBean.set(beanName);

		try {
			// 调用Supplier获取bean实例
			// 这允许用户通过自定义逻辑控制bean的创建过程
			instance = instanceSupplier.get();
		}
		finally {
			// 恢复当前创建的bean上下文
			// 确保线程局部变量在创建完成后恢复到之前的状态
			if (outerBean != null) {
				this.currentlyCreatedBean.set(outerBean);
			}
			else {
				this.currentlyCreatedBean.remove();
			}
		}

		// 处理Supplier返回null的情况
		// 使用NullBean占位符表示空值，避免返回null
		if (instance == null) {
			instance = new NullBean();
		}

		// 创建BeanWrapper包装实例，用于后续的属性填充和初始化
		BeanWrapper bw = new BeanWrapperImpl(instance);

		// 初始化BeanWrapper，设置类型转换器、属性编辑器等
		// 这些配置将影响后续的属性注入过程
		initBeanWrapper(bw);

		return bw;
	}
	/**
	 * Overridden in order to implicitly register the currently created bean as
	 * dependent on further beans getting programmatically retrieved during a
	 * {@link Supplier} callback.
	 * @since 5.0
	 * @see #obtainFromSupplier
	 */
	@Override
	protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		String currentlyCreatedBean = this.currentlyCreatedBean.get();
		if (currentlyCreatedBean != null) {
			registerDependentBean(beanName, currentlyCreatedBean);
		}

		return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
	}
	/**
	 * 确定给定bean的候选构造函数，通过检查所有注册的SmartInstantiationAwareBeanPostProcessor后置处理器。
	 * 该方法允许Spring的扩展机制参与构造函数解析过程，支持基于注解（如@Autowired）或其他策略的智能构造函数推断。
	 *
	 * @param beanClass 要创建的bean的原始Class对象
	 * @param beanName 要创建的bean的名称
	 * @return 返回候选构造函数数组，如果没有找到则返回null
	 * @throws org.springframework.beans.BeansException 如果处理过程中发生错误
	 * @see org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
	 */
	@Nullable
	protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
			throws BeansException {

		// 检查beanClass是否存在且已注册了InstantiationAwareBeanPostProcessor类型的后置处理器
		if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
			// 遍历所有注册的BeanPostProcessor
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				// 筛选出SmartInstantiationAwareBeanPostProcessor类型的后置处理器
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					// 调用后置处理器的determineCandidateConstructors方法获取候选构造函数
					Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
					// 如果后置处理器返回了候选构造函数，则直接返回，不再继续检查其他后置处理器
					if (ctors != null) {
						return ctors;
					}
				}
			}
		}
		// 如果没有找到候选构造函数或未注册相关后置处理器，则返回null
		return null;
	}

	/**
	 * 使用默认构造函数实例化给定的bean。
	 * 该方法负责创建bean的实例并封装到BeanWrapper中，是Spring Bean创建流程的核心环节之一。
	 *
	 * @param beanName 要创建的bean的名称，用于标识和查找对应的bean定义
	 * @param mbd 该bean的根级BeanDefinition，包含了bean的所有配置信息（如class、scope等）
	 * @return 封装了新创建bean实例的BeanWrapper对象，提供对bean属性的访问和设置能力
	 */
	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this; // 当前bean工厂的引用

			// 安全管理器环境下的特权操作（Java安全策略相关）
			if (System.getSecurityManager() != null) {
				// 使用特权操作创建bean实例，避免安全检查异常
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
								getInstantiationStrategy().instantiate(mbd, beanName, parent),
						getAccessControlContext());
			}
			else {
				// 非安全管理器环境下直接创建bean实例
				// 调用实例化策略（默认CglibSubclassingInstantiationStrategy或SimpleInstantiationStrategy）
				// 内部通过反射或CGLIB实现对象创建
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}

			// 将新创建的bean实例封装到BeanWrapper实现类中
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);

			// 初始化BeanWrapper：
			// 1. 设置ConversionService（类型转换服务）
			// 2. 注册自定义属性编辑器（PropertyEditor）
			// 3. 配置其他与属性操作相关的上下文
			initBeanWrapper(bw);

			return bw; // 返回封装了bean实例的BeanWrapper，供后续属性填充和初始化使用
		}
		catch (Throwable ex) {
			// 异常处理：创建失败时抛出BeanCreationException，包含详细的失败信息
			throw new BeanCreationException(
					mbd.getResourceDescription(), // 资源描述（如XML文件位置）
					beanName, // bean名称
					"Instantiation of bean failed", // 错误描述
					ex); // 原始异常
		}
	}

	/**
	 * 使用命名的工厂方法实例化bean。该方法可以是静态的（如果mbd参数指定了一个类而不是factoryBean），
	 * 也可以是通过依赖注入配置的工厂对象上的实例方法。
	 *
	 * 此方法支持两种工厂方法场景：
	 * 1. 静态工厂方法：通过bean定义中的class属性和factoryMethodName指定
	 * 2. 实例工厂方法：通过factoryBean属性和factoryMethodName指定
	 *
	 * @param beanName 要创建的bean名称
	 * @param mbd 该bean的根bean定义，包含工厂方法和构造参数信息
	 * @param explicitArgs 通过getBean方法以编程方式传递的显式参数，
	 *                     若为null则使用bean定义中配置的构造参数值
	 * @return 新实例的BeanWrapper，提供对bean属性的访问和设置能力
	 * @see #getBean(String, Object[]) 调用此方法时可传递显式参数
	 */
	protected BeanWrapper instantiateUsingFactoryMethod(
			String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {

		// 委托给ConstructorResolver处理工厂方法实例化逻辑
		// ConstructorResolver负责解析构造函数/工厂方法及其参数
		return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
	}

	/**
	 * "autowire constructor" (with constructor arguments by type) behavior.
	 * Also applied if explicit constructor argument values are specified,
	 * matching all remaining arguments with beans from the bean factory.
	 * <p>This corresponds to constructor injection: In this mode, a Spring
	 * bean factory is able to host components that expect constructor-based
	 * dependency resolution.
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @param ctors the chosen candidate constructors
	 * @param explicitArgs argument values passed in programmatically via the getBean method,
	 * or {@code null} if none (-> use constructor argument values from bean definition)
	 * @return a BeanWrapper for the new instance
	 */
	protected BeanWrapper autowireConstructor(
			String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

		return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
	}

	/**
	 * 使用bean定义中的属性值填充给定BeanWrapper中的bean实例。
	 * 此方法处理属性注入的核心逻辑，包括自动装配和后置处理器回调。
	 *
	 * @param beanName 要创建的bean的名称
	 * @param mbd 该bean的根bean定义
	 * @param bw 持有bean实例的BeanWrapper，可能为null
	 */
	@SuppressWarnings("deprecation")  // 用于兼容postProcessPropertyValues方法
	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		// 处理BeanWrapper为null的情况
		if (bw == null) {
			if (mbd.hasPropertyValues()) {
				// 当BeanWrapper为null但有属性值要应用时抛出异常
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			} else {
				// 无属性值需要设置时直接返回
				return;
			}
		}

		// 阶段1：实例化后处理器检查
		// 允许InstantiationAwareBeanPostProcessor在属性设置前修改bean状态
		// 可用于支持字段注入等特殊注入方式
		boolean continueWithPropertyPopulation = true;

		// 非合成bean且存在实例化后处理器时执行检查
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					// 调用后处理器的实例化后回调，允许其阻止属性填充
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

		// 如果后处理器阻止了属性填充，则终止处理
		if (!continueWithPropertyPopulation) {
			return;
		}

		// 阶段2：处理自动装配
		// 获取bean定义中的属性值，就是xmlProperty赋值的时候
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		// 处理按名称或类型的自动装配
		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			// 创建新的可变属性值对象
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// 按名称自动装配：查找与bean属性同名的其他bean
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}

			// 按类型自动装配：查找与bean属性类型匹配的其他bean
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}

			// 使用自动装配后的属性值
			pvs = newPvs;
		}

		// 阶段3：应用后置处理器修改属性值
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		PropertyDescriptor[] filteredPds = null;
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}

			// 遍历所有后置处理器，允许其修改属性值,说人话，主要功能是解析注解的
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

					// 调用新版的属性处理回调,就是在这里处理处理，	@Autowired @Resource注解
					//如果像自己实现一个类似这样的注解，那么就需要实现InstantiationAwareBeanPostProcessor接口
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);

					// 兼容旧版API
					if (pvsToUse == null) {
						if (filteredPds == null) {
							// 过滤出需要进行依赖检查的属性描述符
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}

		// 阶段4：依赖检查（如果需要）
		if (needsDepCheck) {
			if (filteredPds == null) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			// 检查必需的依赖项是否已设置
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}

		// 阶段5：应用最终的属性值到bean实例
		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}
	/**
	 * 当自动装配模式设置为"byName"时，将工厂中其他bean的引用填充到当前bean的缺失属性中。
	 * 此方法实现了基于属性名的自动装配逻辑：
	 * 1. 查找当前bean中所有未被显式设置值的非简单属性
	 * 2. 检查容器中是否存在与属性名同名的bean
	 * 3. 若存在，则将该bean注入到当前属性中
	 *
	 * @param beanName 当前正在装配的bean名称，用于日志调试
	 * @param mbd 当前bean的定义信息，包含属性设置和自动装配模式
	 * @param bw 包装了目标bean实例的BeanWrapper，用于获取属性描述符
	 * @param pvs 用于存储自动装配结果的可变属性值集合
	 */
	protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		// 1. 获取所有需要自动装配的属性名（未被显式设置值的非简单属性）
		// 非简单属性指的是：非原始类型、非字符串、非日期等基本类型的属性
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);

		// 2. 遍历每个需要自动装配的属性
		for (String propertyName : propertyNames) {
			// 3. 检查容器中是否存在与属性名同名的bean
			if (containsBean(propertyName)) {
				try {
					// 4. 通过bean名称获取对应的bean实例
					Object bean = getBean(propertyName);

					// 5. 将获取到的bean实例添加到属性值集合中
					pvs.add(propertyName, bean);

					// 6. 注册依赖关系：记录propertyName对应的bean被beanName依赖
					// 用于处理销毁顺序和循环依赖检测
					registerDependentBean(propertyName, beanName);

					// 7. 记录自动装配成功的调试信息
					if (logger.isTraceEnabled()) {
						logger.trace("Added autowiring by name from bean name '" + beanName +
								"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
					}
				} catch (BeansException ex) {
					// 处理bean获取失败的情况
					if (logger.isWarnEnabled()) {
						logger.warn("Autowiring by name failed to resolve bean named '" + propertyName +
								"' for property '" + propertyName + "' of bean '" + beanName + "'", ex);
					}
				}
			}
			else {
				// 8. 记录未找到匹配bean的调试信息
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}

	/**
	 * 实现 "按类型自动装配" 的核心逻辑（通过属性类型匹配依赖项）。
	 * 此方法会查找容器中与bean属性类型匹配的唯一bean，并自动注入。
	 *
	 * 工作机制：
	 * 1. 遍历当前bean中所有未显式设置值的非简单属性
	 * 2. 对每个属性，查找容器中类型匹配的候选bean
	 * 3. 如果找到唯一匹配的bean，则注入该属性
	 * 4. 如果存在多个匹配项，则根据优先级或名称进行选择
	 *
	 * 与PicoContainer的默认行为类似，但存在以下差异：
	 * - 当存在多个候选bean时，Spring会尝试解决歧义（如通过@Primary注解）
	 * - PicoContainer则会直接抛出异常
	 *
	 * @param beanName 当前正在装配的bean名称
	 * @param mbd 当前bean的合并定义信息
	 * @param bw 包装目标bean的BeanWrapper，用于获取属性描述符
	 * @param pvs 用于存储自动装配结果的属性值集合
	 */
	protected void autowireByType(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		// 获取类型转换器，用于处理类型转换
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw; // 默认使用BeanWrapper作为类型转换器
		}

		// 记录已自动装配的bean名称，用于注册依赖关系
		Set<String> autowiredBeanNames = new LinkedHashSet<>(4);

		// 获取所有需要自动装配的属性（未设置值的非简单属性）
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);

		// 遍历每个需要自动装配的属性
		for (String propertyName : propertyNames) {
			try {
				// 获取属性描述符
				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);

				// 排除Object类型的属性（无意义进行类型匹配）
				if (Object.class != pd.getPropertyType()) {
					// 获取属性的写方法参数，用于依赖解析
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);

					// 是否允许提前初始化候选bean（非PriorityOrdered类型的bean允许提前初始化）
					boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());

					// 创建依赖描述符，用于解析依赖关系
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);

					// 解析依赖：查找匹配的bean实例
					Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);

					// 注入解析到的依赖
					if (autowiredArgument != null) {
						pvs.add(propertyName, autowiredArgument);
					}

					// 注册依赖关系（记录哪些bean被当前bean依赖）
					for (String autowiredBeanName : autowiredBeanNames) {
						registerDependentBean(autowiredBeanName, beanName);
						if (logger.isTraceEnabled()) {
							logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
									propertyName + "' to bean named '" + autowiredBeanName + "'");
						}
					}

					// 清空临时集合，准备处理下一个属性
					autowiredBeanNames.clear();
				}
			}
			catch (BeansException ex) {
				// 处理依赖解析失败的情况
				throw new UnsatisfiedDependencyException(
						mbd.getResourceDescription(), beanName, propertyName, ex);
			}
		}
	}

	/**
	 * Return an array of non-simple bean properties that are unsatisfied.
	 * These are probably unsatisfied references to other beans in the
	 * factory. Does not include simple properties like primitives or Strings.
	 * @param mbd the merged bean definition the bean was created with
	 * @param bw the BeanWrapper the bean was created with
	 * @return an array of bean property names
	 * @see org.springframework.beans.BeanUtils#isSimpleProperty
	 */
	protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
		Set<String> result = new TreeSet<>();
		PropertyValues pvs = mbd.getPropertyValues();
		PropertyDescriptor[] pds = bw.getPropertyDescriptors();
		for (PropertyDescriptor pd : pds) {
			if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
					!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
				result.add(pd.getName());
			}
		}
		return StringUtils.toStringArray(result);
	}

	/**
	 * Extract a filtered set of PropertyDescriptors from the given BeanWrapper,
	 * excluding ignored dependency types or properties defined on ignored dependency interfaces.
	 * @param bw the BeanWrapper the bean was created with
	 * @param cache whether to cache filtered PropertyDescriptors for the given bean Class
	 * @return the filtered PropertyDescriptors
	 * @see #isExcludedFromDependencyCheck
	 * @see #filterPropertyDescriptorsForDependencyCheck(org.springframework.beans.BeanWrapper)
	 */
	protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw, boolean cache) {
		PropertyDescriptor[] filtered = this.filteredPropertyDescriptorsCache.get(bw.getWrappedClass());
		if (filtered == null) {
			filtered = filterPropertyDescriptorsForDependencyCheck(bw);
			if (cache) {
				PropertyDescriptor[] existing =
						this.filteredPropertyDescriptorsCache.putIfAbsent(bw.getWrappedClass(), filtered);
				if (existing != null) {
					filtered = existing;
				}
			}
		}
		return filtered;
	}

	/**
	 * Extract a filtered set of PropertyDescriptors from the given BeanWrapper,
	 * excluding ignored dependency types or properties defined on ignored dependency interfaces.
	 * @param bw the BeanWrapper the bean was created with
	 * @return the filtered PropertyDescriptors
	 * @see #isExcludedFromDependencyCheck
	 */
	protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw) {
		List<PropertyDescriptor> pds = new ArrayList<>(Arrays.asList(bw.getPropertyDescriptors()));
		pds.removeIf(this::isExcludedFromDependencyCheck);
		return pds.toArray(new PropertyDescriptor[0]);
	}

	/**
	 * Determine whether the given bean property is excluded from dependency checks.
	 * <p>This implementation excludes properties defined by CGLIB and
	 * properties whose type matches an ignored dependency type or which
	 * are defined by an ignored dependency interface.
	 * @param pd the PropertyDescriptor of the bean property
	 * @return whether the bean property is excluded
	 * @see #ignoreDependencyType(Class)
	 * @see #ignoreDependencyInterface(Class)
	 */
	protected boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) {
		return (AutowireUtils.isExcludedFromDependencyCheck(pd) ||
				this.ignoredDependencyTypes.contains(pd.getPropertyType()) ||
				AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces));
	}

	/**
	 * Perform a dependency check that all properties exposed have been set,
	 * if desired. Dependency checks can be objects (collaborating beans),
	 * simple (primitives and String), or all (both).
	 * @param beanName the name of the bean
	 * @param mbd the merged bean definition the bean was created with
	 * @param pds the relevant property descriptors for the target bean
	 * @param pvs the property values to be applied to the bean
	 * @see #isExcludedFromDependencyCheck(java.beans.PropertyDescriptor)
	 */
	protected void checkDependencies(
			String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, @Nullable PropertyValues pvs)
			throws UnsatisfiedDependencyException {

		int dependencyCheck = mbd.getDependencyCheck();
		for (PropertyDescriptor pd : pds) {
			if (pd.getWriteMethod() != null && (pvs == null || !pvs.contains(pd.getName()))) {
				boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType());
				boolean unsatisfied = (dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_ALL) ||
						(isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE) ||
						(!isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
				if (unsatisfied) {
					throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(),
							"Set this property value or disable dependency checking for this bean.");
				}
			}
		}
	}
	/**
	 * 将给定的属性值应用到目标 bean 实例上，解析所有对其他 bean 的运行时引用。
	 * 必须使用深拷贝，以避免永久修改原始属性值。
	 *
	 * @param beanName 用于提供更详细异常信息的 bean 名称
	 * @param mbd      合并后的 bean 定义
	 * @param bw       包装目标对象的 BeanWrapper
	 * @param pvs      新的属性值集合
	 */
	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		// 如果没有属性值需要应用，直接返回
		if (pvs.isEmpty()) {
			return;
		}

		// 如果存在安全管理器，设置 BeanWrapper 的安全上下文
		if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
		}

		// 用于存储可修改的属性值集合
		MutablePropertyValues mpvs = null;
		// 原始属性值列表
		List<PropertyValue> original;

		// 检查属性值集合是否为可修改类型
		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			// 如果属性值已经转换过，直接应用
			if (mpvs.isConverted()) {
				try {
					bw.setPropertyValues(mpvs);
					return;
				} catch (BeansException ex) {
					throw new BeanCreationException(
							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
				}
			}
			// 获取原始属性值列表
			original = mpvs.getPropertyValueList();
		} else {
			// 对于不可修改的属性值集合，转换为列表
			original = Arrays.asList(pvs.getPropertyValues());
		}

		// 获取自定义类型转换器，如果没有则使用 BeanWrapper 本身
		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		// 创建 BeanDefinition 值解析器，用于解析属性值中的 bean 引用
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

		// 创建原始属性值的深拷贝，解析所有引用
		List<PropertyValue> deepCopy = new ArrayList<>(original.size());
		// 标记是否有属性值需要解析
		boolean resolveNecessary = false;

		// 遍历所有原始属性值
		for (PropertyValue pv : original) {
			// 如果属性值已经转换过，直接添加到深拷贝列表
			if (pv.isConverted()) {
				deepCopy.add(pv);
			} else {
				// 获取属性名和原始值
				String propertyName = pv.getName();
				Object originalValue = pv.getValue();

				// 处理自动装配标记
				if (originalValue == AutowiredPropertyMarker.INSTANCE) {
					// 获取属性的写方法
					Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
					if (writeMethod == null) {
						throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
					}
					// 创建依赖描述符
					originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
				}

				// 解析属性值（如果是对其他 bean 的引用，会在这里解析）
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
				// 转换后的属性值
				Object convertedValue = resolvedValue;

				// 检查属性是否可写且不是嵌套或索引属性
				boolean convertible = bw.isWritableProperty(propertyName) &&
						!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);

				// 如果属性可写，进行类型转换
				if (convertible) {
					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
				}

				// 处理不同情况下的属性值存储
				if (resolvedValue == originalValue) {
					// 如果解析后的值与原始值相同，可能只是类型转换
					if (convertible) {
						pv.setConvertedValue(convertedValue);
					}
					deepCopy.add(pv);
				} else if (convertible && originalValue instanceof TypedStringValue &&
						!((TypedStringValue) originalValue).isDynamic() &&
						!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
					// 特殊情况处理：静态字符串值转换
					pv.setConvertedValue(convertedValue);
					deepCopy.add(pv);
				} else {
					// 需要解析的情况，创建新的 PropertyValue 对象
					resolveNecessary = true;
					deepCopy.add(new PropertyValue(pv, convertedValue));
				}
			}
		}

		// 如果所有属性值都不需要解析，标记为已转换
		if (mpvs != null && !resolveNecessary) {
			mpvs.setConverted();
		}

		// 应用深拷贝后的属性值到 BeanWrapper
		try {
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		} catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}
	/**
	 * Convert the given value for the specified target property.
	 */
	@Nullable
	private Object convertForProperty(
			@Nullable Object value, String propertyName, BeanWrapper bw, TypeConverter converter) {

		if (converter instanceof BeanWrapperImpl) {
			return ((BeanWrapperImpl) converter).convertForProperty(value, propertyName);
		}
		else {
			PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
			MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
			return converter.convertIfNecessary(value, pd.getPropertyType(), methodParam);
		}
	}


	/**
	 * Initialize the given bean instance, applying factory callbacks
	 * as well as init methods and bean post processors.
	 * <p>Called from {@link #createBean} for traditionally defined beans,
	 * and from {@link #initializeBean} for existing bean instances.
	 * @param beanName the bean name in the factory (for debugging purposes)
	 * @param bean the new bean instance we may need to initialize
	 * @param mbd the bean definition that the bean was created with
	 * (can also be {@code null}, if given an existing bean instance)
	 * @return the initialized bean instance (potentially wrapped)
	 * @see BeanNameAware
	 * @see BeanClassLoaderAware
	 * @see BeanFactoryAware
	 * @see #applyBeanPostProcessorsBeforeInitialization
	 * @see #invokeInitMethods
	 * @see #applyBeanPostProcessorsAfterInitialization
	 */
	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

	private void invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

	/**
	 * Give a bean a chance to react now all its properties are set,
	 * and a chance to know about its owning bean factory (this object).
	 * This means checking whether the bean implements InitializingBean or defines
	 * a custom init method, and invoking the necessary callback(s) if it does.
	 * @param beanName the bean name in the factory (for debugging purposes)
	 * @param bean the new bean instance we may need to initialize
	 * @param mbd the merged bean definition that the bean was created with
	 * (can also be {@code null}, if given an existing bean instance)
	 * @throws Throwable if thrown by init methods or by the invocation process
	 * @see #invokeCustomInitMethod
	 */
	protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {

		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
						((InitializingBean) bean).afterPropertiesSet();
						return null;
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
				((InitializingBean) bean).afterPropertiesSet();
			}
		}

		if (mbd != null && bean.getClass() != NullBean.class) {
			String initMethodName = mbd.getInitMethodName();
			if (StringUtils.hasLength(initMethodName) &&
					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}

	/**
	 * Invoke the specified custom init method on the given bean.
	 * Called by invokeInitMethods.
	 * <p>Can be overridden in subclasses for custom resolution of init
	 * methods with arguments.
	 * @see #invokeInitMethods
	 */
	protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
			throws Throwable {

		String initMethodName = mbd.getInitMethodName();
		Assert.state(initMethodName != null, "No init method set");
		Method initMethod = (mbd.isNonPublicAccessAllowed() ?
				BeanUtils.findMethod(bean.getClass(), initMethodName) :
				ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));

		if (initMethod == null) {
			if (mbd.isEnforceInitMethod()) {
				throw new BeanDefinitionValidationException("Could not find an init method named '" +
						initMethodName + "' on bean with name '" + beanName + "'");
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("No default init method named '" + initMethodName +
							"' found on bean with name '" + beanName + "'");
				}
				// Ignore non-existent default lifecycle methods.
				return;
			}
		}

		if (logger.isTraceEnabled()) {
			logger.trace("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");
		}
		Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);

		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				ReflectionUtils.makeAccessible(methodToInvoke);
				return null;
			});
			try {
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
						methodToInvoke.invoke(bean), getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
				InvocationTargetException ex = (InvocationTargetException) pae.getException();
				throw ex.getTargetException();
			}
		}
		else {
			try {
				ReflectionUtils.makeAccessible(methodToInvoke);
				methodToInvoke.invoke(bean);
			}
			catch (InvocationTargetException ex) {
				throw ex.getTargetException();
			}
		}
	}


	/**
	 * Applies the {@code postProcessAfterInitialization} callback of all
	 * registered BeanPostProcessors, giving them a chance to post-process the
	 * object obtained from FactoryBeans (for example, to auto-proxy them).
	 * @see #applyBeanPostProcessorsAfterInitialization
	 */
	@Override
	protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
		return applyBeanPostProcessorsAfterInitialization(object, beanName);
	}

	/**
	 * Overridden to clear FactoryBean instance cache as well.
	 */
	@Override
	protected void removeSingleton(String beanName) {
		synchronized (getSingletonMutex()) {
			super.removeSingleton(beanName);
			this.factoryBeanInstanceCache.remove(beanName);
		}
	}

	/**
	 * Overridden to clear FactoryBean instance cache as well.
	 */
	@Override
	protected void clearSingletonCache() {
		synchronized (getSingletonMutex()) {
			super.clearSingletonCache();
			this.factoryBeanInstanceCache.clear();
		}
	}

	/**
	 * Expose the logger to collaborating delegates.
	 * @since 5.0.7
	 */
	Log getLogger() {
		return logger;
	}


	/**
	 * Special DependencyDescriptor variant for Spring's good old autowire="byType" mode.
	 * Always optional; never considering the parameter name for choosing a primary candidate.
	 */
	@SuppressWarnings("serial")
	private static class AutowireByTypeDependencyDescriptor extends DependencyDescriptor {

		public AutowireByTypeDependencyDescriptor(MethodParameter methodParameter, boolean eager) {
			super(methodParameter, false, eager);
		}

		@Override
		public String getDependencyName() {
			return null;
		}
	}


	/**
	 * {@link MethodCallback} used to find {@link FactoryBean} type information.
	 */
	private static class FactoryBeanMethodTypeFinder implements MethodCallback {

		private final String factoryMethodName;

		private ResolvableType result = ResolvableType.NONE;

		FactoryBeanMethodTypeFinder(String factoryMethodName) {
			this.factoryMethodName = factoryMethodName;
		}

		@Override
		public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
			if (isFactoryBeanMethod(method)) {
				ResolvableType returnType = ResolvableType.forMethodReturnType(method);
				ResolvableType candidate = returnType.as(FactoryBean.class).getGeneric();
				if (this.result == ResolvableType.NONE) {
					this.result = candidate;
				}
				else {
					Class<?> resolvedResult = this.result.resolve();
					Class<?> commonAncestor = ClassUtils.determineCommonAncestor(candidate.resolve(), resolvedResult);
					if (!ObjectUtils.nullSafeEquals(resolvedResult, commonAncestor)) {
						this.result = ResolvableType.forClass(commonAncestor);
					}
				}
			}
		}

		private boolean isFactoryBeanMethod(Method method) {
			return (method.getName().equals(this.factoryMethodName) &&
					FactoryBean.class.isAssignableFrom(method.getReturnType()));
		}

		ResolvableType getResult() {
			Class<?> resolved = this.result.resolve();
			boolean foundResult = resolved != null && resolved != Object.class;
			return (foundResult ? this.result : ResolvableType.NONE);
		}
	}

}
